识别虚拟网卡:Node.js 获取真实物理网卡的 MAC 地址

您所在的位置:网站首页 js 获取mac地址 识别虚拟网卡:Node.js 获取真实物理网卡的 MAC 地址

识别虚拟网卡:Node.js 获取真实物理网卡的 MAC 地址

2023-03-29 02:02| 来源: 网络整理| 查看: 265

在依据 Electron 的使用中,有一个业务需求是获取物理网卡的 Mac 地址以用于客户机唯一性识别。

刚接到需求时你或许会想,这还不简单,调用 Node.js 的 os 模块提供的 networkInterfaces API 就行了。所以立刻开干:

import { networkInterfaces } from 'os'; function isZeroMac(mac) { return /^(0{1,2}[:-]){5}0{1,2}$/.test(mac); } function getMac(family = 'IPv4') { const nif = networkInterfaces(); for (const list of Object.values(nif)) { const item = list.find(d => !d.internal && !isZeroMac(d.mac) && (!d.family ||d.family === family)); if (item) return item.mac; } return ''; }

两分钟就写完了,测验一下返回值也与 ipconfig/ifconfig 打印的信息一致,满怀信心的提交代码完工。

测验同学当天验证了一下表示没什么问题,然而第二天却找上门了:同一台电脑今昨两天取到的值不一样。经过各种排查剖析,最终才发现本来这位测验妹妹因疫情管控居家了,用着 VPN 长途接入工作网络干活呢。

本来开 VPN 的时分使用了虚拟网卡,此时你才发现工作并没有那么简单。实际上,在存在 VPN、虚拟机等场景下,都或许会使用到虚拟网卡。

1. 依据 networkInterfaces 返回值的字段值过滤

networkInterfaces 能够获取到一切网卡的基本信息,可依据 internal、mac 等字段的值做一次过滤,得到有用的信息:

const isValid = (item) => item.internal === false && !isZeroMac(item.mac);

可是对于 VPN、虚拟机等存在虚拟网卡的场景下,仅依据该信息无法进行有用区分。

2. 依据虚拟网卡 Mac 特征过滤

如果能够得到虚拟网卡的特征,则可依据相关特征点进行识别与过滤。

依据某内部项目长达六年的实践积累以及参阅 vscode 中类似的完成,咱们得到了一个常见虚拟网卡默许 Mac 地址特征的列表,参阅如下:

// see https://standards-oui.ieee.org/oui/oui.txt const virtualMacPrefix = new Set([ '00:05:69', // vmware1 '00:0c:29', // vmware2 '00:50:56', // vmware3 '00:1c:14', // vmware '00:1c:42', // parallels1 '02:00:4c', // Microsoft Loopback Adapter (微软回环网卡) '00:03:ff', // microsoft virtual pc '00:0f:4b', // virtual iron 4 '00:16:3e', // red hat xen , oracle vm , xen source, novell xen '08:00:27', // virtualbox ]);

所以能够据此完成一个是否为虚拟网卡的判断办法 isVirtualMac:

export function isMac(mac: string) { return /^([da-f]{1,2}[:-]){5}([da-f]{1,2})$/i.test(mac); } export function formatMac(mac: string) { return String(mac).trim().toLowerCase().replace(/-/g, ':'); } export function isVirtualMac(mac: string) { return isMac(mac) && virtualMacPrefix.has(formatMac(mac).slice(0, 8)); }

据此可对 getMac 办法改进如下:

function getMac(family = 'IPv4') { const nif = networkInterfaces(); for (const list of Object.values(nif)) { const item = list.find(d => !d.internal && !isZeroMac(d.mac) && (!d.family ||d.family === family) && !isVirtualMac(d.mac)); if (item) return item.mac; } return ''; } 3. 依据描绘关键字特征过滤

在 Windows 体系下,能够经过执行 ipconfig /all 或 wmic nic get 命令得到一切网卡的概况,其中包含了描绘信息。

依据实践经验剖析,咱们总结了一个常见虚拟网卡描绘关键字的特征列表,参阅如下:

const virtualDescList = ['virtual', ' vpn ', ' ssl ', 'tap-windows', 'hyper-v', 'km-test', 'microsoft loopback'];

若经过前述规矩过滤之后仍然存在多个网卡信息,则可持续获取网卡概况,并依据 virtualDescList 列表以测验进一步的过滤处理:

// 执行 wmic nic get 命令获取一切网卡概况 function getNetworkIFacesInfoByWmic() { // 略 } if (hasMutiMac(list)) { const info = await getNetworkIFacesInfoByWmic(); list = list.filter(item => { if (!info.config[item.mac]) return true; const desc = String(info.config[item.mac].desc).toLowerCase(); return !virtualDescList.some(d => desc.includes(d)); }); }

getNetworkIFacesInfoByWmic 办法的详细完成能够拜见这儿:

github.com/lzwme/get-p…

4. 按优先级规矩排序

过滤办法会将视为无效的项扫除,可是或许会因规矩的误差而导致最终得到的列表为空。为了防止这种或许现象的出现,能够将过滤扫除改为优先级排序办法,最终取列表第一项视为最优选项。

排序办法完成示例:

/** * sort by: !internal > !zeroMac(mac) > visual > family=IPv4 */ function ifacesSort(list: NetworkInterfaceInfo[]) { return list.sort((a, b) => { if (a.internal !== b.internal) return a.internal ? 1 : -1; if (isZeroMac(a.mac) !== isZeroMac(b.mac)) return isZeroMac(a.mac) ? 1 : -1; const isVirtualA = isVirtualMac(a.mac); const isVirtualB = isVirtualMac(b.mac); if (isVirtualA !== isVirtualB) return isVirtualA ? 1 : -1; if (a.family !== b.family) return a.family === 'IPv6' ? 1 : -1; }); }

所以最终的逻辑大致如下:

获取悉数网卡信息 依据 iface 特征排序获得悉数列表:en0 - mac, eth3 - linux, ethernet - windows 优先级更高 依据 internal字段、虚拟网卡特征(mac)、family字段等进行排序 对排序的成果进行基础过滤:internal=true、isZeroMac 若过滤后列表多于1个,则依据虚拟网卡特征持续过滤 若过滤成果仍多余1个,则依据描绘特征持续过滤 取最终成果的第一项作为最优选择

识别虚拟网卡:Node.js 获取实在物理网卡的 MAC 地址

5. 总结与参阅

实际上社区里已经有 address、getmac和macaddress 等较为流行的相关库,但它们都不触及虚拟网卡的识别。 本文主要介绍了依据实践经验对虚拟网卡的识别处理办法,与 vscode 中的相关完成逻辑较为类似,但又增加了依据描绘信息过滤的规矩逻辑。

www.npmjs.com/package/add… www.npmjs.com/package/get… www.npmjs.com/package/mac… github.com/sebhildebra… github.com/microsoft/v… github.com/lzwme/get-p… lzw.me/a/nodejs-ge…


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3